package com.tsfyun.scm.service.impl.customer;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.Snowflake;
import com.google.common.collect.Lists;
import com.tsfyun.common.base.exception.ServiceException;
import com.tsfyun.common.base.util.LocalDateTimeUtils;
import com.tsfyun.common.base.util.StringUtils;
import com.tsfyun.common.base.util.TsfPreconditions;
import com.tsfyun.scm.entity.customer.*;
import com.tsfyun.scm.mapper.customer.CustomerExpressQuoteMapper;
import com.tsfyun.scm.service.customer.*;
import com.tsfyun.common.base.extension.ServiceImpl;
import com.tsfyun.scm.util.ExpressQuoteUtil;
import com.tsfyun.scm.util.TsfWeekendSqls;
import com.tsfyun.scm.vo.customer.CustomerExpressQuoteMemberVO;
import com.tsfyun.scm.vo.customer.CustomerExpressQuotePlusVO;
import com.tsfyun.scm.vo.customer.CustomerExpressQuoteVO;
import com.tsfyun.scm.vo.customer.ExpressStandardQuoteMemberVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * <p>
 * 客户快递模式代理费报价 服务实现类
 * </p>
 *
 *
 * @since 2020-10-30
 */
@Service
@Slf4j
public class CustomerExpressQuoteServiceImpl extends ServiceImpl<CustomerExpressQuote> implements ICustomerExpressQuoteService {

    @Autowired
    private IExpressStandardQuoteService expressStandardQuoteService;

    @Autowired
    private ICustomerExpressQuoteMemberService customerExpressQuoteMemberService;

    @Autowired
    private CustomerExpressQuoteMapper customerExpressQuoteMapper;

    @Autowired
    private IExpressStandardQuoteMemberService expressStandardQuoteMemberService;

    @Autowired
    private ICustomerService customerService;

    @Autowired
    private Snowflake snowflake;

    @Override
    public CustomerExpressQuote getExistsCustomerQuote(Long customerId,String quoteType) {
        List<CustomerExpressQuote> dataList = customerExpressQuoteMapper.selectByExample(Example.builder(CustomerExpressQuote.class).where(TsfWeekendSqls.<CustomerExpressQuote>custom()
                .andEqualTo(false,CustomerExpressQuote::getQuoteType,quoteType)
                .andEqualTo(false,CustomerExpressQuote::getDisabled,Boolean.FALSE)
                .andGreaterThan(false,CustomerExpressQuote::getQuoteEndTime, LocalDateTime.now().plusDays(-1))
                .andEqualTo(false,CustomerExpressQuote::getCustomerId,customerId)).build());
        if(CollUtil.isEmpty(dataList)) {
            return null;
        }
        if(dataList.size() > 1) {
            log.error("客户存在多条启用的有效的代理费报价");
            return null;
        }
        return dataList.get(0);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void createCustomerExpressQuoteByStandard(Long customerId) {
        List<ExpressStandardQuote> standardQuotes = expressStandardQuoteService.getAllEffectiveStandardQuote();
        TsfPreconditions.checkArgument(CollUtil.isNotEmpty(standardQuotes),new ServiceException("系统未配置有效的代理费报价信息"));
        Map<String,List<ExpressStandardQuote>> standardQuoteMap = standardQuotes.stream().collect(Collectors.groupingBy(ExpressStandardQuote::getQuoteType));
        standardQuoteMap.forEach((k,v)->{
            TsfPreconditions.checkArgument(v.size() < 2,new ServiceException("业务模式【%s】存在多条有效标准报价"));
        });
        //如果已存在客户代理费报价，则先删除之
        CustomerExpressQuote condition = new CustomerExpressQuote();
        condition.setCustomerId(customerId);
        List<CustomerExpressQuote> existsCustomerExpressQuote = super.list(condition);
        if(CollUtil.isNotEmpty(existsCustomerExpressQuote)) {
            existsCustomerExpressQuote.stream().forEach(customerExpressQuote -> {
                customerExpressQuoteMemberService.deleteAllCustomerExpressQuoteMembers(customerExpressQuote.getCustomerId());
                super.removeById(customerExpressQuote.getId());
            });
        }
        standardQuoteMap.forEach((k,v)->{
            CustomerExpressQuote customerExpressQuote = beanMapper.map(v.get(0),CustomerExpressQuote.class);
            customerExpressQuote.setCustomerId(customerId);
            customerExpressQuote.setQuoteStartTime(LocalDateTime.now());
            super.saveNonNull(customerExpressQuote);
            //保存客户报价明细
            customerExpressQuoteMemberService.saveCustomerExpressQuoteMembers(customerExpressQuote.getId(),v.get(0).getId());
        });

    }

    @Override
    public CustomerExpressQuotePlusVO getCustomerExpressQuote(Long customerId, String quoteType) {
        CustomerExpressQuotePlusVO customerExpressQuotePlusVO;
        if(Objects.isNull(customerId)) {
            customerExpressQuotePlusVO = getStandardExpressQuote(quoteType);
        } else {
            CustomerExpressQuote customerExpressQuote = null;
            List<CustomerExpressQuote> dataList = customerExpressQuoteMapper.selectByExample(Example.builder(CustomerExpressQuote.class).where(TsfWeekendSqls.<CustomerExpressQuote>custom()
                    .andEqualTo(false,CustomerExpressQuote::getQuoteType,quoteType)
                    .andEqualTo(false,CustomerExpressQuote::getDisabled,Boolean.FALSE)
                    .andGreaterThan(false,CustomerExpressQuote::getQuoteEndTime, LocalDateTime.now().plusDays(-1))
                    .andEqualTo(false,CustomerExpressQuote::getCustomerId,customerId)).build());
            if(CollUtil.isEmpty(dataList)) {
                log.info("客户【{}】暂还未生成代理费报价【{}】，取标准代理费报价信息",customerId,quoteType);
                return getStandardExpressQuote(quoteType);
            } else if(dataList.size() == 1) {
                customerExpressQuote = dataList.get(0);
            } else if(dataList.size() > 1) {
                log.error("客户【{}】存在多条启用的有效的代理费报价【{}】",customerId,quoteType);
                throw new ServiceException("客户代理费报价信息有误");
            }
            List<CustomerExpressQuoteMember> members = customerExpressQuoteMemberService.findByQuoteId(customerExpressQuote.getId());
            customerExpressQuotePlusVO = new CustomerExpressQuotePlusVO(beanMapper.map(customerExpressQuote, CustomerExpressQuoteVO.class),
                    beanMapper.mapAsList(members, CustomerExpressQuoteMemberVO.class));
        }
        if(CollUtil.isNotEmpty(customerExpressQuotePlusVO.getMembers())) {
            customerExpressQuotePlusVO.getMembers().stream().forEach(member->{
                member.setFastAmount(ExpressQuoteUtil.calculate(member.getStartWeight(),
                        beanMapper.map(customerExpressQuotePlusVO.getCustomerExpressQuote(),CustomerExpressQuote.class),
                        beanMapper.mapAsList(customerExpressQuotePlusVO.getMembers(),CustomerExpressQuoteMember.class)));
            });
        }
        return customerExpressQuotePlusVO;
    }

    @Override
    public CustomerExpressQuotePlusVO getStandardExpressQuote(String quoteType) {
        List<ExpressStandardQuote> standardQuotes = expressStandardQuoteService.getAllEffectiveStandardQuote();
        TsfPreconditions.checkArgument(CollUtil.isNotEmpty(standardQuotes),new ServiceException("系统未配置有效的代理费报价信息"));
        Map<String,List<ExpressStandardQuote>> standardQuoteMap = standardQuotes.stream().collect(Collectors.groupingBy(ExpressStandardQuote::getQuoteType));
        List<ExpressStandardQuote> expressStandardQuotes = standardQuoteMap.get(quoteType);
        TsfPreconditions.checkArgument(CollUtil.isNotEmpty(expressStandardQuotes) && expressStandardQuotes.size() == 1,new ServiceException("系统配置的代理费报价信息有误"));
        ExpressStandardQuote expressStandardQuote = expressStandardQuotes.get(0);
        //获取报价明细信息
        List<ExpressStandardQuoteMember> members = expressStandardQuoteMemberService.findByQuoteId(expressStandardQuote.getId());
        return new CustomerExpressQuotePlusVO(beanMapper.map(expressStandardQuote,CustomerExpressQuoteVO.class),
                beanMapper.mapAsList(members, CustomerExpressQuoteMemberVO.class));
    }

    @Override
    public CustomerExpressQuotePlusVO getCustomerExpressQuoteByName(String customerName, String quoteType) {
        if(StringUtils.isEmpty(customerName)) {
            return getCustomerExpressQuote(null,quoteType);
        }
        Customer customer = customerService.findByNameWithRight(customerName);
        if(Objects.isNull(customer)) {
            return getCustomerExpressQuote(null,quoteType);
        }
        return getCustomerExpressQuote(customer.getId(),quoteType);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public CustomerExpressQuote saveByBaseExpressQuote(Long customerId,String quoteType, List<ExpressStandardQuoteMemberVO> expressStandardQuoteMemberVOList) {
        CustomerExpressQuote customerExpressQuote = new CustomerExpressQuote();
        customerExpressQuote.setCustomerId(customerId);
        customerExpressQuote.setQuoteType(quoteType);
        customerExpressQuote.setQuoteStartTime(LocalDateTimeUtils.convertLocalDate());//生效日期
        customerExpressQuote.setQuoteEndTime(LocalDateTimeUtils.parse("2099-01-01 00:00:00","yyyy-MM-dd HH:mm:ss")); //失效日期
        customerExpressQuote.setCapped(expressStandardQuoteMemberVOList.get(0).getCapped());
        customerExpressQuote.setCappedFee(expressStandardQuoteMemberVOList.get(0).getCappedFee());
        customerExpressQuote.setDisabled(Boolean.FALSE);
        super.saveNonNull(customerExpressQuote);
        //保存明细
        List<CustomerExpressQuoteMember> memberList = Lists.newArrayList();
        expressStandardQuoteMemberVOList.stream().forEach(vo ->{
            CustomerExpressQuoteMember member = new CustomerExpressQuoteMember();
            member.setId(snowflake.nextId());
            member.setQuoteId(customerExpressQuote.getId());
            member.setStartWeight(vo.getStartWeight());
            member.setEndWeight(vo.getEndWeight());
            member.setBasePrice(vo.getBasePrice());
            member.setPrice(vo.getPrice());
            memberList.add(member);
        });
        customerExpressQuoteMemberService.savaBatch(memberList);
        return customerExpressQuote;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeByAgreementId(Long agreementId) {
        customerExpressQuoteMapper.removeByAgreementId(agreementId);
    }
}
